package
{
import core.Configuration;
import core.FlashCookie;
import core.FlashVars;
import core.StageProxy;
import core.log.GameLogType;
import core.log.GameLogger;

import flash.display.DisplayObject;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.events.Event;
import flash.net.URLRequest;
import flash.utils.getDefinitionByName;

import tracking.GameTracker;

import utils.URLUtil;
import utils.Version;

/**
 * Preloader. Show loading progress and waiting UI 
 * @author jliang
 * 
 */
public class Preloader extends MovieClip implements IPreloader
{
	public function Preloader()
	{		
		if (stage) 
		{
			init();
		}
		else
		{
			this.addEventListener(Event.ADDED_TO_STAGE, addToStageHandler);
		}
	}
    //==========================================================================
    //  Variables
    //==========================================================================
    private var loader : Loader;    
    private var loaderFlag : Boolean = false;
    //==========================================================================
    //  Public methods
    //==========================================================================
	public function setFlashParams(params:Object):void
	{
		FlashVars.initialize(params);
	}
	
    public function dispose():void
    {
        this.removeEventListener(Event.ENTER_FRAME, loadingCheck);
        
        if (this.parent)
        {
            this.parent.removeChild(this);
        }
        
        if ( loader ) {
            loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, preloaderLoadedHandler );
        }
    }
    
    private var progress:Number = 0;
    
    public function updateProgress(progress:Number):void
    {
        trace("Loading: " + progress + "%");
        this.progress = progress;
		
		if (loader && loader.content && loader.content.hasOwnProperty("progress"))
		{
			loader.content["progress"] = progress;
		}
    }
    //==========================================================================
    //  Private methods
    //==========================================================================
    private function init():void
    {		
        //init basic static class
		StageProxy.stage = stage;
		
        Version.initialize(this);
        
        GameLogger.setTrackingManager(new GameTracker());
        
        FlashCookie.initialize();
		
		FlashVars.initialize(this.loaderInfo.parameters);
		
		Configuration.initBasicConfig();
        
        GameLogger.log(GameLogType.START_PRELOAD);
        
    	this.addEventListener(Event.ENTER_FRAME, loadingCheck);
		
		initLoader();
    }
	
	private function addToStageHandler(event:Event):void
	{
		this.removeEventListener(Event.ADDED_TO_STAGE, addToStageHandler);
		
		init();
	}
    
    private function initLoader() : void 
    {        
        loader = new Loader();
        var urlreq : URLRequest = URLUtil.getRequest(Configuration.assetsPath + Configuration.gamePreloaderPath);
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, preloaderLoadedHandler );
        loader.load( urlreq );
        
    }
    
    private function preloaderLoadedHandler ( event : Event) : void 
    {
        event.target.removeEventListener(Event.COMPLETE, preloaderLoadedHandler );
        
        addChildAt(loader.content, 0);
        
        loaderFlag = true;
        
        updateProgress( progress );
        
        loadingCheck(null);
    }
    
    private function initApp():void
    {	
        this.gotoAndStop(2);
        
        var mainClass:Class = Class(getDefinitionByName("Main"));
        var app:DisplayObject = new mainClass() as DisplayObject;
        stage.addChild(app);
        IApp(app).init(this);
    }
    
    private function loadProgress():void
    {
        updateProgress(Math.round(20 * this.loaderInfo.bytesLoaded / this.loaderInfo.bytesTotal));
    }
    
    private function loadedCompleted():void
    {
        this.removeEventListener(Event.ENTER_FRAME, loadingCheck);
        
        loaderFlag && initApp();
    }
    //==========================================================================
    //  Event handlers
    //==========================================================================    
    private function loadingCheck(event:Event):void
    {
    	if (this.loaderInfo.bytesLoaded >= this.loaderInfo.bytesTotal)
    	{
    	   loadedCompleted();
    	}
    	else
    	{
    	   loadProgress();
    	}
    }
}
}